// --------------------------------------------------------------------------------------------------------------------
// <copyright file="JVideoInfoStruct.cs" company="Jarno Burger / Dennis de Bruijn">
//   Jarno Burger / Dennis de Bruijn
// </copyright>
// <summary>
//   Structure containing the frame properties
//   size = 16 bytes
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ManagedFreeFrame.Struct
{
    using System.Globalization;
    using System.Runtime.InteropServices;

    /// <summary>
    ///   Structure containing the frame properties
    ///   size = 16 bytes
    /// </summary>
    /// <remarks>
    /// All video data in FreeFrame is pixel ordered, 
    /// so the R, G, B values of a single pixel are located at consecutive memory locations. 
    /// A video buffer consists of FrameWidth x FrameHeight pixels. 
    /// 
    /// Plugins using 32-bit as byte aligned 24-bit video should be careful not to overwrite the alpha 
    /// (4th) byte of each pixel (e.g. by using it as a processing space) 
    /// as this may be used soon by hosts with 32-bit video processing becoming more accessible. 
    /// 
    /// If Orientation == 1 the first pixel at the pointer to the frame is the top left pixel. 
    /// If Orientation == 2, it is the bottom left pixel. 
    /// This is particularly important for text and live input (to avoid mirroring of the image). 
    /// 
    /// The byte order of color values depends on the target platform (i.e. big-endian versus little-endian). 
    /// For little-endian platforms (e.g. Intel PC), the byte order is BGRA for 32-bit and BGR for 24-bit colors. 
    /// For big-endian machines (e.g. MAC), the byte order for 32-bit is ARGB and RGB for 24-bit.
    /// 
    /// For all target platforms, the unsigned integer representation of a 32-bit color is the same, namely (in C syntax): 
    /// where A, R, G, B are the 8-bit color components. Plugin developers who aim for platform-independence should be aware of these differences and program their plugins accordingly. 
    /// </remarks>
    // ReSharper disable MemberCanBeInternal
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct VideoInfoStruct
    {
        /// <summary>
        ///   width of frame in pixels
        /// 32-bit unsigned integer
        /// </summary>
        [MarshalAs(UnmanagedType.U4)] 
        public uint FrameWidth;

        /// <summary>
        ///   height of frame in pixels
        /// 32-bit unsigned integer
        /// </summary>
        [MarshalAs(UnmanagedType.U4)] 
        public uint FrameHeight;

        /// <summary>
        ///   enumerated indicator of bit depth of video: 0 = 16 bit 5-6-5   1 = 24bit packed   2 = 32bit
        /// 32-bit unsigned integer
        /// </summary>
        [MarshalAs(UnmanagedType.U4)] 
        public uint BitDepth;

        /// <summary>
        ///   Current meaningful values (see remarks):
        ///   1 = origin at top left
        ///   2 = origin at bottom left
        ///   If Orientation == 1 the first pixel at the pointer to the frame is the top left pixel. 
        ///   If Orientation == 2, it is the bottom left pixel. 
        ///   This is particularly important for text and live input (to avoid mirroring of the image).
        /// 32-bit unsigned integer

        /// </summary>
        [MarshalAs(UnmanagedType.U4)] 
        public uint Orientation;

        /// <summary>
        ///   Returns a <see cref = "System.String" /> that represents this instance.
        /// </summary>
        /// <returns>
        ///   A <see cref = "System.String" /> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            var w = this.FrameWidth.ToString(CultureInfo.InvariantCulture);
            var h = this.FrameHeight.ToString(CultureInfo.InvariantCulture);
            var d = string.Empty;
            var o = string.Empty;

            switch (this.BitDepth)
            {
                case 0:
                    d = "16";
                    break;
                case 1:
                    d = "24";
                    break;
                case 2:
                    d = "32";
                    break;
            }

            switch (this.Orientation)
            {
                case 0:
                    o = "top left";
                    break;
                case 1:
                    o = "bottom left";
                    break;
            }

            return "w:" + w + "px h:" + h + "px d:" + d + "bit o:" + o;
        }

        /// <summary>
        ///   whether the structure is OK
        /// </summary>
        /// <returns><see langword="true"/> if it could be ok</returns>
        public bool NotOk()
        {
            if (this.FrameWidth <= 0)
            {
                return true;
            }

            if (this.FrameHeight <= 0)
            {
                return true;
            }

            if ((this.BitDepth > 2))
            {
                return true;
            }

            return (this.Orientation < 1) || (this.Orientation > 2);
        }
    }
    // ReSharper restore MemberCanBeInternal
}